package dao;

import java.util.ArrayList;
import java.util.List;
import org.hibernate.LockMode;
import org.hibernate.Query;
import static org.hibernate.criterion.Example.create;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A data access object (DAO) providing persistence and search support for
 * Examination entities. Transaction control of the save(), update() and
 * delete() operations can directly support Spring container-managed
 * transactions or they can be augmented to handle user-managed Spring
 * transactions. Each of these methods provides additional information for how
 * to configure it for the desired type of transaction control.
 * 
 * @see dao.Examination
 * @author MyEclipse Persistence Tools
 */

public class ExaminationDAO extends BaseHibernateDAO {
    private static final Logger log = LoggerFactory
	    .getLogger(ExaminationDAO.class);
    // property constants
    public static final String COURSEID = "courseid";
    public static final String CHAPTERID = "chapterid";
    public static final String KNOWLEDGEID = "knowledgeid";
    public static final String TYPE = "type";
    public static final String QUESTION = "question";
    public static final String ANSWER = "answer";
    public static final String ANALYSIS = "analysis";

    public boolean save(Examination transientInstance) {
	return save(log, "saving Examination instance", transientInstance);
    }

    public boolean delete(Examination persistentInstance) {
	return delete(log, "deleting Examination instance", persistentInstance);
    }

    public Examination findById(java.lang.Integer id) {
	log.debug("getting Examination instance with id: " + id);
	try {
	    Examination instance = (Examination) getSession().get(
		    "dao.Examination", id);
	    return instance;
	} catch (RuntimeException re) {
	    log.error("get failed", re);
	    throw re;
	}
    }

    public List<Examination> findByExample(Examination instance) {
	log.debug("finding Examination instance by example");
	try {
	    List<Examination> results = (List<Examination>) getSession()
		    .createCriteria("dao.Examination").add(create(instance))
		    .list();
	    log.debug("find by example successful, result size: "
		    + results.size());
	    return results;
	} catch (RuntimeException re) {
	    log.error("find by example failed", re);
	    throw re;
	}
    }

    public List findByProperty(String propertyName, Object value) {
	log.debug("finding Examination instance with property: " + propertyName
		+ ", value: " + value);
	try {
	    String queryString = "from Examination as model where model."
		    + propertyName + "= ?";
	    Query queryObject = getSession().createQuery(queryString);
	    queryObject.setParameter(0, value);
	    return queryObject.list();
	} catch (RuntimeException re) {
	    log.error("find by property name failed", re);
	    throw re;
	}
    }

    public List<Examination> findByCourseid(Object courseid) {
	return findByProperty(COURSEID, courseid);
    }

    public List<Examination> findByChapterid(Object chapterid) {
	return findByProperty(CHAPTERID, chapterid);
    }

    public List<Examination> findByKnowledgeid(Object knowledgeid) {
	return findByProperty(KNOWLEDGEID, knowledgeid);
    }

    public List<Examination> findByType(Object type) {
	return findByProperty(TYPE, type);
    }

    public List<Examination> findByQuestion(Object question) {
	return findByProperty(QUESTION, question);
    }

    public List<Examination> findByAnswer(Object answer) {
	return findByProperty(ANSWER, answer);
    }

    public List<Examination> findByAnalysis(Object analysis) {
	return findByProperty(ANALYSIS, analysis);
    }

    public List findAll() {
	log.debug("finding all Examination instances");
	try {
	    String queryString = "from Examination";
	    Query queryObject = getSession().createQuery(queryString);
	    return queryObject.list();
	} catch (RuntimeException re) {
	    log.error("find all failed", re);
	    throw re;
	}
    }

    public Examination merge(Examination detachedInstance) {
	log.debug("merging Examination instance");
	try {
	    Examination result = (Examination) getSession().merge(
		    detachedInstance);
	    log.debug("merge successful");
	    return result;
	} catch (RuntimeException re) {
	    log.error("merge failed", re);
	    throw re;
	}
    }

    public List<Examination> getExaminationByType2(String chapterid, int type,
	    List<Integer> examinationids, int topNumber,
	    List<Integer> knowledgeids) {
	try {
	    StringBuilder buffer = new StringBuilder(
		    "from Examination where examinationid in (select min(exa1.examinationid) from Examination as exa1 where exa1.examinationid in(select b from Examination as b where b.chapterid=? and b.knowledgeid in(");
	    for (int num : knowledgeids) {
		buffer.append(num).append(",");
	    }
	    buffer.replace(buffer.length()-1, buffer.length(), ")");
	    buffer.append(" and b.type=?) GROUP BY exa1.knowledgeid)");
	    if (examinationids != null)
		if (examinationids.size() > 0) {
		    buffer.append(" and examinationid not in(");
		    for (int num : examinationids) {
			buffer.append(num).append(",");
		    }
		    buffer.replace(buffer.length()-1, buffer.length(), ")");
		}
	    Query queryObject = getSession().createQuery(buffer.toString());
	    queryObject.setParameter(0, chapterid);
	    queryObject.setParameter(1, type);
	    queryObject.setFirstResult(0);
	    queryObject.setMaxResults(topNumber);
	    return queryObject.list();
	} catch (RuntimeException re) {
	    log.error("find by property name failed", re);
	    throw re;
	}
    }
    
    public List<Examination> getExaminationByType3(int type,List<Integer> examinationids, int topNumber,List<Integer> knowledgeids) {
	try {
	    StringBuilder buffer = new StringBuilder(
		    "from Examination where examinationid in (select min(exa1.examinationid) from Examination as exa1 where exa1.examinationid in(select b from Examination as b where b.knowledgeid in(");
	    for (int num : knowledgeids) {
		buffer.append(num).append(",");
	    }
	    buffer.replace(buffer.length()-1, buffer.length(), ")");
	    buffer.append(" and b.type=?) GROUP BY exa1.knowledgeid)");
	    if (examinationids != null)
		if (examinationids.size() > 0) {
		    buffer.append(" and examinationid not in(");
		    for (int num : examinationids) {
			buffer.append(num).append(",");
		    }
		    buffer.replace(buffer.length()-1, buffer.length(), ")");
		}
	    Query queryObject = getSession().createQuery(buffer.toString());
	    queryObject.setParameter(0, type);
	    queryObject.setFirstResult(0);
	    queryObject.setMaxResults(topNumber);
	    return queryObject.list();
	} catch (RuntimeException re) {
	    log.error("find by property name failed", re);
	    throw re;
	}
    }
    
    public List<Examination> getExaminationByType() {
	try {
	    StringBuilder buffer = new StringBuilder(
		    "from Examination where chapterid='010101' and knowledgeid in(3,2");
	    buffer.append(") and type=1");
	    Query queryObject = getSession().createQuery(buffer.toString());
	    return queryObject.list();
	} catch (RuntimeException re) {
	    log.error("find by property name failed", re);
	    throw re;
	}
    }

    public boolean update(Examination instance) {
	return update(log, "updating Examination instance", instance);
    }

    public List<Integer> getExaminationNumbers(String type, String chapterid) {
	List<Integer> list = new ArrayList<Integer>();
	try {
	    String sqlString = "select count(examinationid) from Examination where chpaterid=? and type=?";
	    Query queryObject = getSession().createQuery(sqlString);
	    queryObject.setParameter(0, chapterid);
	    queryObject.setParameter(1, type);
	    Integer counts1 = (Integer) queryObject.uniqueResult();
	    list.add(counts1);

	    sqlString = "select distinct (count knowledgeid) from Examination where chpaterid=? and type=?";
	    queryObject = getSession().createQuery(sqlString);
	    queryObject.setParameter(0, chapterid);
	    queryObject.setParameter(1, type);
	    Integer counts2 = (Integer) queryObject.uniqueResult();
	    list.add(counts2);

	    sqlString = "select distinct (count knowledgeid) from Examination where chpaterid=?";
	    queryObject = getSession().createQuery(sqlString);
	    queryObject.setParameter(0, chapterid);
	    queryObject.setParameter(1, type);
	    Integer counts3 = (Integer) queryObject.uniqueResult();
	    list.add(counts3);
	    return list;
	} catch (RuntimeException re) {
	    throw re;
	}
    }

    public List<Integer> getKnowledgeids(String chapterid,
	    List<Integer> knowledgeids, int topNumber) {
	try {
	    StringBuilder buffer = new StringBuilder(
		    "select distinct knowledgeid from Examination where chapterid=?");
	    if (knowledgeids != null)
		if (knowledgeids.size() > 0) {
		    buffer = new StringBuilder(
			    "select distinct knowledgeid from Examination where chapterid=? and knowledgeid not in (");
		    for (int num : knowledgeids) {
			buffer.append(num).append(",");
		    }
		    buffer.replace(buffer.length()-1, buffer.length(), ")");
		}
	    Query queryObject = getSession().createQuery(buffer.toString());
	    queryObject.setParameter(0, chapterid);
	    queryObject.setFirstResult(0);
	    queryObject.setMaxResults(topNumber);
	    return queryObject.list();
	} catch (RuntimeException re) {
	    throw re;
	}
    }
    
    public List<Integer> getKnowledgeids2(List<Integer> knowledgeids, int topNumber) {
	try {
	    StringBuilder buffer = new StringBuilder(
		    "select distinct knowledgeid from Examination");
	    if (knowledgeids != null)
		if (knowledgeids.size() > 0) {
		    buffer = new StringBuilder(
			    "select distinct knowledgeid from Examination where knowledgeid not in (");
		    for (int num : knowledgeids) {
			buffer.append(num).append(",");
		    }
		    buffer.replace(buffer.length()-1, buffer.length(), ")");
		}
	    Query queryObject = getSession().createQuery(buffer.toString());
	    queryObject.setFirstResult(0);
	    queryObject.setMaxResults(topNumber);
	    return queryObject.list();
	} catch (RuntimeException re) {
	    throw re;
	}
    }


    public List<Integer> getPreleKnowledgeids(String chapterid,
	    List<Integer> errorKnowledgeids, int topNum) {
	try {
	    StringBuilder builder = new StringBuilder(
		    "select distinct (knowledgeid) from Examination where chapterid=? and knowledgeid in(");
	    for (int id : errorKnowledgeids) {
		builder.append(id).append(",");
	    }
	    builder.replace(builder.length()-1, builder.length(), ")");
	    Query queryObject = getSession().createQuery(builder.toString());
	    queryObject.setParameter(0, chapterid);
	    queryObject.setFirstResult(0);
	    queryObject.setMaxResults(topNum);
	    return queryObject.list();
	} catch (RuntimeException re) {
	    throw re;
	}
    }
    
    public List<Integer> getPreleKnowledgeids2( List<Integer> errorKnowledgeids, int topNum) {
	try {
	    StringBuilder builder = new StringBuilder(
		    "select distinct (knowledgeid) from Examination where knowledgeid in(");
	    for (int id : errorKnowledgeids) {
		builder.append(id).append(",");
	    }
	    builder.replace(builder.length()-1, builder.length(), ")");
	    Query queryObject = getSession().createQuery(builder.toString());
	    queryObject.setFirstResult(0);
	    queryObject.setMaxResults(topNum);
	    return queryObject.list();
	} catch (RuntimeException re) {
	    throw re;
	}
    }

    public int getKnowledgeCount(String chapterid, List<Integer> knowledgeids) {
	try {
	    StringBuilder builder = new StringBuilder(
		    "select count(distinct knowledgeid) from Examination where chapterid=?");
	    if (knowledgeids != null) {
		if (knowledgeids.size() > 0) {
		    builder.append(" and knowledgeid not in (");
		    for (int num : knowledgeids) {
			builder.append(num).append(",");
		    }
		    builder.replace(builder.length()-1, builder.length(), ")");
		}
	    }
	    Query queryObject = getSession().createQuery(builder.toString());
	    queryObject.setParameter(0, chapterid);
	    return ((Number) queryObject.uniqueResult()).intValue();

	} catch (RuntimeException re) {
	    throw re;
	}
    }

    public void attachClean(Examination instance) {
	log.debug("attaching clean Examination instance");
	try {
	    getSession().lock(instance, LockMode.NONE);
	    log.debug("attach successful");
	} catch (RuntimeException re) {
	    log.error("attach failed", re);
	    throw re;
	}
    }
    public static void main(String[] args){
	List<Integer> list1 = new ArrayList<Integer>();
	List<Integer> list2 = new ArrayList<Integer>();
	list1.add(3);
	list2.add(2);
	list2.add(4);
	list2.add(3);
	List<Examination> list = new ExaminationDAO().getExaminationByType3(2, null,5, list2);
	System.out.println(list.size());
    }
}